package com.demo.base.utils;

import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
import org.springframework.core.NamedThreadLocal;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;


/**
 * 日期工具类
 * <p>
 * Created by ethan on 2017/2/16.
 */
public abstract class DateUtil {

    public static final String DATE_PATTERN = "yyyy-MM-dd";

    public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_PATTERN_YMDH = "yyyyMMddHH";

    public static final ThreadLocal<DateFormat> ymdh = new NamedThreadLocal<DateFormat>("date format yyyymmddhh") {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(DATE_PATTERN_YMDH);
        }
    };

    public static void main(String[] args) {
        System.out.println(ymdh.get().format(new Date()));
    }

    //Date类型和String类型互转

    /**
     * 转为日期格式字符串（不包含时间部分）
     */
    public static String formatAsDate(Date date) {
        return formatDate(date, DATE_PATTERN);
    }

    /**
     * 转为日期+时间格式字符串
     */
    public static String formatAsDateTime(Date date) {
        return formatDate(date, DATE_TIME_PATTERN);
    }

    /**
     * 格式化date类型为字符串
     */
    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 按照指定格式转换输入字符串为date类型
     */
    public static Date parseDate(String input, String pattern) {
        try {
            return new SimpleDateFormat(pattern).parse(input);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 按照指定格式转换输入字符串为date类型
     */
    public static Date parseDate(String input) {
        if (StringUtils.isEmpty(input)) {
            return null;
        }
        try {
            long tms = Long.parseLong(input);
            return new Date(tms);
        } catch (Exception e) {
            try {
                return new ISO8601DateFormat().parse(input);
            } catch (ParseException e0) {
                return null;
            }
        }

    }


    //java8 本地化时间与Date互转

    /**
     * date类型转为对应的本地时间（java8）
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * 本地时间转为date类型（java8）
     */
    public static Date fromLocalDateTime(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * date类型转为对应的本地日期（java8）
     */
    public static LocalDate toLocalDate(Date date) {
        return toLocalDateTime(date).toLocalDate();
    }

    /**
     * 本地日期转为date类型（java8）
     */
    public static Date fromLocalDate(LocalDate localDate) {
        return fromLocalDateTime(localDate.atStartOfDay());
    }

    //因目前大家仍习惯使用Date类型处理时间，所以基于java8的time包实现几个基本的时间差计算工具类

    /**
     * 在指定时间上添加指定时间，并返回计算后的时间
     */
    public static Date plus(Date time, long amountToAdd, ChronoUnit unit) {
        LocalDateTime newTime = toLocalDateTime(time).plus(amountToAdd, unit);
        return fromLocalDateTime(newTime);
    }

    /**
     * 在指定时间上减去指定时间，并返回计算后的时间
     */
    public static Date minus(Date time, long amountToAdd, ChronoUnit unit) {
        LocalDateTime newTime = toLocalDateTime(time).minus(amountToAdd, unit);
        return fromLocalDateTime(newTime);
    }

    /**
     * 计算指定两个日期的时间间隔
     */
    public static Duration duration(Date left, Date right) {
        return Duration.between(toLocalDateTime(left), toLocalDateTime(right));
    }

    //业务中常用的方法

    /**
     * 计算周年
     */
    public static long computeFullYear(Date input) {
        Duration duration = Duration.between(
                toLocalDateTime(input),
                LocalDate.now()
        );
        return duration.get(ChronoUnit.YEARS);
    }

    /**
     * 获得昨天的日期
     *
     * @return
     */
    public static String getYesterDayDate(String pattern) {
        DateFormat simpleDateFormat = new SimpleDateFormat(pattern == null ? DateUtil.DATE_PATTERN : pattern);
        Calendar toDay = Calendar.getInstance();
        toDay.setTime(new Date());
        toDay.add(Calendar.DAY_OF_MONTH, -1);//获得昨天的时间
        Date ytDay = toDay.getTime();
        return simpleDateFormat.format(ytDay);
    }

    /***
     * 过去7天
     */
    public static String getWeek() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar lastDate = Calendar.getInstance();
        lastDate.roll(Calendar.DATE, -7);//日期回滚7天
        str = sdf.format(lastDate.getTime());
        System.out.println(str);
        return str;
    }

    /***
     * 过去30天
     */
    public static String getmonth() {
        Date date = new Date();
        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(s.format(date));
        String str1 = s.format(date);//当前的时间
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -30);//计算30天后的时间
        String str2 = s.format(c.getTime());
        return str2;
    }

    public static String getToday() {
        Date dt = new Date();
        SimpleDateFormat matter1 = new SimpleDateFormat("yyyy-MM-dd");
        return matter1.format(dt);
    }

}
